package com.ezgo.erc.master.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;

/**
 * 
 * (工具)模块 TODO(使用HTTP服务进行GET/POST请求)
 * 
 * @author devintam
 * @date 2015年7月24日 下午2:39:01
 *
 */
@SuppressWarnings("deprecation")
public class HttpClientUtil {
	private final static Logger logger = Logger.getLogger(HttpClientUtil.class);
	private static DefaultHttpClient httpclient;

	/**
	 * 获取post请求结果信息
	 * 
	 * @param url
	 *            提交地址
	 * @param params
	 *            请求参数
	 * @return String
	 */
	public static String post(String url, HashMap<String, String> params) {
		httpclient = new DefaultHttpClient();
		String body = null;

		logger.info("create httppost:" + url);
		HttpPost post = postForm(url, params);

		body = invoke(httpclient, post);

		httpclient.getConnectionManager().shutdown();

		return body;
	}

	/**
	 * 获取post请求结果信息
	 * 
	 * @param url
	 *            提交地址
	 * @param params
	 *            请求参数
	 * @return String
	 */
	public static String postRaw(String url, HashMap<String, String> params) {
		httpclient = new DefaultHttpClient();
		HttpPost post = createMethod(url, params, 6000);
		HttpResponse response = null;
		String body = null;
		try {
			response = httpclient.execute(post);
			int statusCode = response.getStatusLine().getStatusCode();
			// 只要在获取源码中，服务器返回的不是200代码，则统一认为抓取源码失败，返回null。
			if (statusCode != HttpStatus.SC_OK) {
				logger.error("Method failed: " + response.getStatusLine() + "\tstatusCode: " + statusCode);
				body = "404";
			} else
				body = paseResponse(response);
		} catch (ClientProtocolException e) {
			body = "500";
			logger.error(String.format(Constants.EX_FORMAT_STR, HttpClientUtil.class.getName(), e.getMessage()));
		} catch (IOException e) {
			body = "500";
			logger.error(String.format(Constants.EX_FORMAT_STR, HttpClientUtil.class.getName(), e.getMessage()));
		}
		return body;
	}

	/**
	 * 获取get请求字符串
	 * 
	 * @param url
	 *            提交地址
	 * @return String
	 */
	public static String get(String url) {
		httpclient = new DefaultHttpClient();
		String body = null;

		logger.info("create httpget:" + url);
		HttpGet get = new HttpGet(url);
		body = invoke(httpclient, get);

		httpclient.getConnectionManager().shutdown();

		return body;
	}

	/**
	 * 获取回复内容
	 * 
	 * @param httpclient
	 *            http客户端对象
	 * @param httpost
	 *            请求对象(HttpPost、HttpGet)
	 * @return String
	 */
	private static String invoke(DefaultHttpClient httpclient, HttpUriRequest httpost) {
		HttpResponse response = sendRequest(httpclient, httpost);
		String body = paseResponse(response);
		return body;
	}

	/**
	 * 解析回复内容信息
	 * 
	 * @param response
	 *            回复对象
	 * @return String
	 */
	private static String paseResponse(HttpResponse response) {
		logger.info("get response from httpserver..");
		HttpEntity entity = response.getEntity();

		logger.info("response status:" + response.getStatusLine());
		String charset = EntityUtils.getContentCharSet(entity);
		logger.info(charset);

		String body = null;
		try {
			body = EntityUtils.toString(entity);
			logger.info(StringUtil.abbr(body, 50));
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return body;
	}

	/**
	 * 发送请求信息
	 * 
	 * @param httpclient
	 *            客户端对象
	 * @param httpost
	 *            请求对象(HttpPost、HttpGet)
	 * @return HttpResponse
	 */
	private static HttpResponse sendRequest(DefaultHttpClient httpclient, HttpUriRequest httpost) {
		logger.info("execute post...");
		HttpResponse response = null;
		try {
			response = httpclient.execute(httpost);
		} catch (ClientProtocolException e) {
			logger.error(String.format(Constants.EX_FORMAT_STR, HttpClientUtil.class.getName(), e.getMessage()));
		} catch (IOException e) {
			logger.error(String.format(Constants.EX_FORMAT_STR, HttpClientUtil.class.getName(), e.getMessage()));
		}
		return response;
	}

	/**
	 * 获取请求表单信息
	 * 
	 * @param url
	 *            提交地址
	 * @param params
	 *            请求参数
	 * @return HttpPost
	 */
	private static HttpPost postForm(String url, HashMap<String, String> params) {
		HttpPost httpost = new HttpPost(url);
		try {
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();

			Set<String> keySet = params.keySet();
			for (String key : keySet) {
				nvps.add(new BasicNameValuePair(key, params.get(key)));
			}
			logger.info("set utf-8 form entity to httppost");
			httpost.setEntity(new UrlEncodedFormEntity(nvps, Constants.DEFAULT_ENCODING));
		} catch (UnsupportedEncodingException e) {
			logger.error(String.format(Constants.EX_FORMAT_STR, HttpClientUtil.class.getName(), e.getMessage()));
		}

		return httpost;
	}

	private static HttpPost createMethod(String url, HashMap<String, String> params, int timeout) {
		HttpPost method = null;
		try {
			method = new HttpPost(url);
			JSONObject jsonObject = new JSONObject();

			Set<String> keySet = params.keySet();
			for (String key : keySet) {
				jsonObject.put(key, params.get(key));
			}
			method.addHeader("Content-type", "application/json; charset=utf-8");
			method.setHeader("Accept", "application/json");
			method.setEntity(new StringEntity(jsonObject.toString(), Constants.DEFAULT_ENCODING));
			// 使用系统提供的默认的恢复策略
			method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
			// 设置超时的时间
			method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, timeout);
		} catch (IllegalArgumentException e) {
			logger.error(String.format("非法的URL：%s", url));
		} catch (Exception e) {
			logger.error(String.format(Constants.EX_FORMAT_STR, HttpClientUtil.class.getName(), e.getMessage()));
		}
		return method;
	}
}
